﻿using GameFramework.ModelManager.SkinnedModelPipeline;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using GameFramework.Materials;

namespace GameFramework.ModelManager
{
    public class SkinnedGameCharacter : AnimatedModel
    {
        public SkinnedGameCharacter()
        {
        }

        public SkinnedGameCharacter(Model model, Vector3 position, Vector3 rotation,
            Vector3 scale, GraphicsDevice graphicsDevice, string name, bool isHuman = false)
            : base(model, position, rotation, scale, graphicsDevice)
        {
            this.name = name;
            this.isHuman = isHuman;
            this.animationPlayer = new SkinnedAnimationPlayer(model.Tag as SkinningData);
        }

        public SkinnedGameCharacter(SkinnedGameCharacter skinnedModel)
            : this(skinnedModel.unmanagedModel, skinnedModel.position, skinnedModel.rotation, skinnedModel.scale,
            skinnedModel.graphicsDevice, skinnedModel.name, skinnedModel.isHuman)

        {
            this.animationPlayer = skinnedModel.animationPlayer;
        }

        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            Matrix world = Matrix.CreateScale(scale) *
                Matrix.CreateFromYawPitchRoll(rotation.Y, rotation.X, rotation.Z) *
                Matrix.CreateTranslation(position);

            TimeSpan elapsedTime = TimeSpan.FromSeconds(
                gameTime.ElapsedGameTime.TotalSeconds * playSpeed);

            animationPlayer.Update(new SkinnedAnimationUpdateParameters(elapsedTime, world));
        }

        public override void Draw(Matrix view, Matrix projection, Vector3 cameraposition)
        {
            SkinnedAnimationPlayer skinnedAnimationPlayer = (SkinnedAnimationPlayer)animationPlayer;

            foreach (ModelMesh mesh in unmanagedModel.Meshes)
            {
                foreach (SkinnedEffect effect in mesh.Effects)
                {
                    effect.SetBoneTransforms(skinnedAnimationPlayer.SkinTransforms);
                    effect.View = view;
                    effect.Projection = projection;
                }

                mesh.Draw();
            }
        }

        protected override void setNewEffect()
        {
            foreach (ModelMesh mesh in unmanagedModel.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    SkinnedEffect newEffect = new SkinnedEffect(graphicsDevice);
                    BasicEffect oldEffect = ((BasicEffect)part.Effect);

                    newEffect.EnableDefaultLighting();
                    newEffect.SpecularColor = Color.Black.ToVector3();

                    newEffect.AmbientLightColor = oldEffect.AmbientLightColor;
                    newEffect.DiffuseColor = oldEffect.DiffuseColor;
                    newEffect.Texture = oldEffect.Texture;

                    part.Effect = newEffect;
                }
            }
        }

        public virtual string Name
        {
            get { return name; }
            set { name = value; }
        }

        public virtual bool IsHuman
        {
            get { return isHuman; }
            set { isHuman = value; }
        }

        protected string name;
        protected bool isHuman;
    }
}
